home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_200 / 204_01 / getsym.c < prev    next >
Text File  |  1980-01-01  |  18KB  |  555 lines

  1. #include        <stdio.h>
  2. #include        "c.h"
  3. #include        "expr.h"
  4. #include        "gen.h"
  5. #include        "cglbdec.h"
  6.  
  7. /*
  8.  *    68000 C compiler
  9.  *
  10.  *    Copyright 1984, 1985, 1986 Matthew Brandt.
  11.  *  all commercial rights reserved.
  12.  *
  13.  *    This compiler is intended as an instructive tool for personal use. Any
  14.  *    use for profit without the written consent of the author is prohibited.
  15.  *
  16.  *    This compiler may be distributed freely for non-commercial use as long
  17.  *    as this notice stays intact. Please forward any enhancements or questions
  18.  *    to:
  19.  *
  20.  *        Matthew Brandt
  21.  *        Box 920337
  22.  *        Norcross, Ga 30092
  23.  */
  24.  
  25. static int      errno[80];
  26. static int      numerrs;
  27. static char     inline[132];
  28. int             total_errors = 0;
  29. char            *lptr;          /* shared with preproc */
  30. FILE            *inclfile[10];  /* shared with preproc */
  31. int             inclline[10];   /* shared with preproc */
  32. int             incldepth;      /* shared with preproc */
  33. char            *linstack[20];  /* stack for substitutions */
  34. char            chstack[20];    /* place to save lastch */
  35. int             lstackptr = 0;  /* substitution stack pointer */
  36.  
  37. int     isalnum(c)
  38. char    c;
  39. {       return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
  40.                 (c >= '0' && c <= '9');
  41. }
  42.  
  43. int     isidch(c)
  44. char    c;
  45. {       return isalnum(c) || c == '_' || c == '$';
  46. }
  47.  
  48. int     isspace(c)
  49. char    c;
  50. {       return c == ' ' || c == '\t' || c == '\n';
  51. }
  52.  
  53. int     isdigit(c)
  54. char    c;
  55. {       return (c >= '0' && c <= '9');
  56. }
  57.  
  58. initsym()
  59. {       lptr = inline;
  60.         inline[0] = 0;
  61.         numerrs = 0;
  62.         total_errors = 0;
  63.         lineno = 0;
  64. }
  65.  
  66. int     getline(listflag)
  67. int     listflag;
  68. {       int     rv;
  69.         if( lineno > 0 && listflag) {
  70.                 fprintf(list,"%6d\t%s",lineno,inline);
  71.                 while(numerrs--)
  72.                         fprintf(list," *** error %d\n",errno[numerrs]);
  73.                 numerrs = 0;
  74.                 }
  75.         ++lineno;
  76.         rv = (fgets(inline,131,input) == NULL);
  77.         if( rv && incldepth > 0 ) {
  78.                 fclose(input);
  79.                 input = inclfile[--incldepth];
  80.                 lineno = inclline[incldepth];
  81.                 return getline(0);
  82.                 }
  83.         if( rv )
  84.                 return 1;
  85.         lptr = inline;
  86.         if(inline[0] == '#')
  87.                 return preprocess();
  88.         return 0;
  89. }
  90.  
  91. /*
  92.  *      getch - basic get character routine.
  93.  */
  94. int     getch()
  95. {       while( (lastch = *lptr++) == '\0') {
  96.                 if( lstackptr > 0 ) {
  97.                         lptr = linstack[--lstackptr];
  98.                         lastch = chstack[lstackptr];
  99.                         return lastch;
  100.                         }
  101.                 if(getline(incldepth == 0))
  102.                         return lastch = -1;
  103.                 }
  104.         return lastch;
  105. }
  106.  
  107. /*
  108.  *      error - print error information
  109.  */
  110. error(n)
  111. int     n;
  112. {       errno[numerrs++] = n;
  113.         ++total_errors;
  114. }
  115.  
  116. /*
  117.  *      getid - get an identifier.
  118.  *
  119.  *      identifiers are any isidch conglomerate
  120.  *      that doesn't start with a numeric character.
  121.  *      this set INCLUDES keywords.
  122.  */
  123. int     getid()
  124. {       register int    i;
  125.         i = 0;
  126.         while(isidch(lastch)) {
  127.                 if(i < 19)
  128.                         lastid[i++] = lastch;
  129.                 getch();
  130.                 }
  131.         lastid[i] = '\0';
  132.         lastst = id;
  133. }
  134.  
  135. /*
  136.  *      getsch - get a character in a quoted string.
  137.  *
  138.  *      this routine handles all of the escape mechanisms
  139.  *      for characters in strings and character constants.
  140.  */
  141. int     getsch()        /* return an in-quote character */
  142. {       register int    i, j;
  143.         if(lastch == '\n')
  144.                 return -1;
  145.         if(lastch != '\\') {
  146.                 i = lastch;
  147.                 getch();
  148.                 return i;
  149.                 }
  150.         getch();        /* get an escaped character */
  151.         if(isdigit(lastch)) {
  152.                 i = 0;
  153.                 for(i = 0;j < 3;++j) {
  154.                         if(lastch <= '7' && lastch >= '0')
  155.                                 i = (i << 3) + lastch - '0';
  156.                         else
  157.                                 break;
  158.                         getch();
  159.                         }
  160.                 return i;
  161.                 }
  162.         i = lastch;
  163.         getch();
  164.         switch(i) {
  165.                 case '\n':
  166.                         getch();
  167.                         return getsch();
  168.                 case 'b':
  169.                         return '\b';
  170.                 case 'f':
  171.                         return '\f';
  172.                 case 'n':
  173.                         return '\n';
  174.                 case 'r':
  175.                         return '\r';
  176.                 case 't':
  177.                         return '\t';
  178.                 default:
  179.                         return i;
  180.                 }
  181. }
  182.  
  183. int     radix36(c)
  184. char    c;
  185. {       if(isdigit(c))
  186.                 return c - '0';
  187.         if(c >= 'a' && c <= 'z')
  188.                 return c - 'a' + 10;
  189.         if(c >= 'A' && c <= 'Z')
  190.                 return c - 'A' + 10;
  191.         return -1;
  192. }
  193.  
  194. /*
  195.  *      getbase - get an integer in any base.
  196.  */
  197. getbase(b)
  198. {       register int    i, j;
  199.         i = 0;
  200.         while(isalnum(lastch)) {
  201.                 if((j = radix36(lastch)) < b) {
  202.                         i = i * b + j;
  203.                         getch();
  204.                         }
  205.                 else break;
  206.                 }
  207.         ival = i;
  208.         lastst = iconst;
  209. }
  210.  
  211. /*
  212.  *      getfrac - get fraction part of a floating number.
  213.  */
  214. getfrac()
  215. {       double  frmul;
  216.         frmul = 0.1;
  217.         while(isdigit(lastch)) {
  218.                 rval += frmul * (lastch - '0');
  219.                 getch();
  220.                 frmul *= 0.1;
  221.                 }
  222. }
  223.  
  224. /*
  225.  *      getexp - get exponent part of floating number.
  226.  *
  227.  *      this algorithm is primative but usefull.  Floating
  228.  *      exponents are limited to +/-255 but most hardware
  229.  *      won't support more anyway.
  230.  */
  231. getexp()
  232. {       double  expo, exmul;
  233.         expo = 1.0;
  234.         if(lastst != rconst)
  235.                 rval = ival;
  236.         if(lastch = '-') {
  237.                 exmul = 0.1;
  238.                 getch();
  239.                 }
  240.         else
  241.                 exmul = 10.0;
  242.         getbase(10);
  243.         if(ival > 255)
  244.                 error(ERR_FPCON);
  245.         else
  246.                 while(ival--)
  247.                         expo *= exmul;
  248.         rval *= expo;
  249. }
  250.  
  251. /*
  252.  *      getnum - get a number from input.
  253.  *
  254.  *      getnum handles all of the numeric input. it accepts
  255.  *      decimal, octal, hexidecimal, and floating point numbers.
  256.  */
  257. getnum()
  258. {       register int    i, j, k;
  259.         i = 0;
  260.         if(lastch == '0') {
  261.                 getch();
  262.                 if(lastch == 'x' || lastch == 'X') {
  263.                         getch();
  264.                         getbase(16);
  265.                         }
  266.                 else getbase(8);
  267.                 }
  268.         else    {
  269.                 getbase(10);
  270.                 if(lastch == '.') {
  271.                         getch();
  272.                         rval = ival;    /* float the integer part */
  273.                         getfrac();      /* add the fractional part */
  274.                         lastst = rconst;
  275.                         }
  276.                 if(lastch == 'e' || lastch == 'E') {
  277.                         getch();
  278.                         getexp();       /* get the exponent */
  279.                         }
  280.                 }
  281. }
  282.  
  283. /*
  284.  *      getsym - get next symbol from input stream.
  285.  *
  286.  *      getsym is the basic lexical analyzer.  It builds
  287.  *      basic tokens out of the characters on the input
  288.  *      stream and sets the following global variables:
  289.  *
  290.  *      lastch:         A look behind buffer.
  291.  *      lastst:         type of last symbol read.
  292.  *      laststr:        last string constant read.
  293.  *      lastid:         last identifier read.
  294.  *      ival:           last integer constant read.
  295.  *      rval:           last